/* 信号量实现，可以实现某些固定的资源数量 */

#include <stdio.h>
#include <stdlib.h>
#include "mysem.h"
#include <pthread.h>

struct mysem_st
{
  int value;
  pthread_mute_t mute;
  pthread_cond_t cond;
};

mysem_t *mysem_init(int initval)
{
  struct mysem_st *me = (struct mysem_st *)malloc(sizeof(*me));
  if (me == NULL) {
    return NULL;
  }

  me->value = initval;
  pthread_mute_init(&me->mute, NULL);
  pthread_cond_init(&me->cond, NULL);

  return me;
}

int mysem_add(mysem_t *sem, int num)
{
  struct mysem_st *me = (struct mysem_st *)sem;
  pthread_mute_lock(&me->mute);
  me->value += num;
  pthread_mute_unlock(&me->mute);
  pthread_cond_broadcast(&me->cond);

  return 0;
}

int mysem_sub(mysem_t *sem, int num)
{
  struct mysem_st *me = (struct mysem_st *)sem;
  pthread_mute_lock(&me->mute);
  while (me->value < num) {
    pthread_cond_wait(&me->cond, &me->mute);
  }
  me->value -= num;
  pthread_mute_unlock(&me->mute);
}

int mysem_destroy(mysem_t *sem)
{
  if (sem == NULL) {
    return -1;
  }
  struct mysem_st *me = (struct mysem_st *)sem;
  pthread_mute_destroy(&me->mute);
  pthread_cond_destroy(&me->cond);
  free(me);

  return 0;
}

